<!DOCTYPE html>
<html lang="en">
<head>
    <title>Renderless Components в React. Как интегрировать неинтегрируемое?</title>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <link rel="stylesheet" href="shower/themes/ribbon/styles/styles.css">
    <style>
        .shower {
            --slide-ratio: calc(16 / 9);
        }
    </style>
    <link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="194x194" href="favicon/favicon-194x194.png">
    <link rel="icon" type="image/png" sizes="192x192" href="favicon/android-chrome-192x192.png">
    <link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
    <link rel="manifest" href="favicon/site.webmanifest">
    <link rel="mask-icon" href="favicon/safari-pinned-tab.svg" color="#5bbad5">
    <link rel="shortcut icon" href="favicon/favicon.ico">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="favicon/mstile-144x144.png">
    <meta name="msapplication-config" content="favicon/browserconfig.xml">
    <meta name="theme-color" content="#ffffff">

    <style>
        html {
            height: 100%;
            width: 100%;
        }

        .shower {
            --slide-gap: 100px;
            --slide-ratio: calc(16 / 9);
            --slide-width: 1024px;
            --slide-height: calc(
                var(--slide-width) / var(--slide-ratio)
            );

            --color-blue: #6897bb;
            --color-blue-lighter: #6897bb;
            --color-red: #cc0000;
            --color-yellow: #fafaa2;
            --color-grey: #585a5e;
            --color-fill: rgba(88, 90, 94, 0.1);
            --color-line: rgba(88, 90, 94, 0.5);

            --ribbon-size: 50px;
            --progress-size: 10px;

            --f-z_xxl: 88px;
            --f-z_xl: 64px;
            --f-z_l: 46px;
            --f-z_m: 32px;
            --f-z_s: 24px;
            --f-z_xs: 16px;
            --f-z_xxs: 12px;
        }

        .slide {
            background-color: #2b2b2b;
        }

        .slide h2 {
            color: #a9b7c6;
        }

        .slide:after {
            background-image: url('pictures/ribbon.svg');
            color: #2b2b2b;
            font-weight: bold;
        }

        .progress:before {
            background-color: #305d78;
        }

        .f-z_xxl {
            font-size: var(--f-z_xxl);
        }

        .f-z_xl {
            font-size: var(--f-z_xl);
        }

        .f-z_l {
            font-size: var(--f-z_l);
        }

        .f-z_m {
            font-size: var(--f-z_m);
        }

        .f-z_s {
            font-size: var(--f-z_s);
        }

        .f-z_xs {
            font-size: var(--f-z_xs);
        }

        .f-z_xxs {
            font-size: var(--f-z_xxs);
        }

        h1 {
            font-size: var(--f-z_xxl);
        }

        h2 {
            font-size: var(--f-z_xl);
            margin: 0 !important;
        }

        h3 {
            font-size: var(--f-z_l);
        }

        h4 {
            font-size: var(--f-z_m);
        }

        h5 {
            font-size: var(--f-z_s);
        }

        h6 {
            font-size: var(--f-z_xs);
        }

        p {
            font-size: var(--f-z_xs);
        }

        .h_full {
            height: 100%;
        }

        .hor__item {
            display: inline-block;
            vertical-align: middle;
        }

        .hor__item_w {
            width: 25%;
        }

        .box {
            display: table;
            height: 100%;
            position: relative;
            width: 100%;
        }

        .box_cover {
            bottom: 0;
            left: 0;
            position: absolute;
            right: 0;
            top: 0;
        }

        .row {
            display: table-row;
            position: relative;
        }

        .col {
            display: table-cell;
            overflow: hidden;
            position: relative;
        }

        .invisible {
            visibility: hidden;
        }

        .offset_20 {
            bottom: 20px;
            left: 20px;
            right: 20px;
            top: 20px;
        }

        .offset_b_20 {
            bottom: 20px;
        }

        .box_gray {
            background-color: #e1e3e4;
        }

        .m_h_20 {
            margin: 0 20px;
        }

        .m_v_20 {
            margin: 20px 0;
        }

        .m_20 {
            margin: 20px;
        }

        .p-t_20 {
            padding-top: 20px;
        }

        .t-a_c {
            text-align: center;
        }

        .v-a_m {
            vertical-align: middle;
        }

        .w_full {
            width: 100%;
        }

        .link_us {
            --us-speed: 200ms;
            display: inline-block;
            font-family: "Trebuchet MS", sans-serif;
            font-size: 36px;
            font-weight: 400;
            letter-spacing: 0;
            line-height: 40px;
            outline: none;
            position: relative;
            text-align: center;
        }

        .link_us,
        .link_us:after,
        .link_us:before {
            height: 40px;
            transition: all calc(6 * var(--us-speed)) ease,
            color calc(3 * var(--us-speed)) ease calc(5 * var(--us-speed)),
            background-color calc(3 * var(--us-speed)) ease calc(5 * var(--us-speed)),
            font-size ease calc(4 * var(--us-speed)),
            font-weight ease calc(4 * var(--us-speed)),
            letter-spacing ease calc(4 * var(--us-speed)),
            width ease calc(4 * var(--us-speed));
            width: 180.56px;
        }

        .link_us:after,
        .link_us:before {
            overflow: hidden;
            content: '';
            bottom: 0;
            left: 0;
            margin: auto;
            pointer-events: none;
            position: absolute;
            right: 0;
            top: 0;
            width: 180.56px;
        }

        .link_us:after {
            color: transparent;
            content: attr(data-title);
            font-size: 36px;
            letter-spacing: 0;
            line-height: 40px;
            position: absolute;
            text-align: center;
            word-break: break-all;
        }

        .link_us:focus,
        .link_us:hover {
            color: transparent;
            cursor: none;
            font-weight: 600;
            transition: all calc(6 * var(--us-speed)) ease calc(2 * var(--us-speed)),
            color calc(3 * var(--us-speed)) ease,
            background-color calc(3 * var(--us-speed)) ease,
            font-size 0ms ease calc(2 * var(--us-speed)),
            font-weight 0ms ease calc(2 * var(--us-speed));
        }

        .link_us:focus:after,
        .link_us:focus:before,
        .link_us:hover:after,
        .link_us:hover:before {
            height: 180.56px;
            pointer-events: all;
            transition: all calc(6 * var(--us-speed)) ease calc(2 * var(--us-speed)),
            color calc(3 * var(--us-speed)) ease,
            background-color calc(3 * var(--us-speed)) ease,
            box-shadow calc(6 * var(--us-speed)) ease calc(6 * var(--us-speed));
        }

        .link_us:focus:before,
        .link_us:hover:before {
            background-color: #000000;
            box-shadow: 0 0 40px -2px rgba(255, 255, 255, 1);
        }

        .link_us:focus:after,
        .link_us:hover:after {
            color: #ffffff;
            font-size: 36px;
            left: 13px;
            letter-spacing: 32px;
            line-height: 53px;
            box-sizing: border-box;
            top: 27px;
        }
        .slide.image .box_cover {
            overflow: auto;
        }
        .slide.image .o_h {
            overflow: hidden;
        }
        .slide.image img {
            max-width: 100%;
            vertical-align: top;
        }
        .slide.qr .box_cover {
            align-items: center;
            display: flex;
            justify-content: center;
        }
        .slide.qr a {
            background: none;
            display: block;
            flex-grow: 1;
        }
        .slide.qr img {
            display: inline-block;
            margin: 12px;
            vertical-align: middle;
        }
    </style>
</head>
<body class="shower list">

    <header class="caption">
        <h1>Renderless Components в React.<br /> Как интегрировать неинтегрируемое?</h1>
        <p>Сухушин Александр</p>
    </header>

    <section class="slide clear" id="intro">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Renderless Components в React.<br /> Как интегрировать неинтегрируемое?</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/react.svg" class="logo-main" alt="react">
                        <div class="logo-small logo-small_1">
                            <div class="logo-small__inner">
                                <img src="pictures/leaflet.svg" class="logo-small__img" alt="leaflet">
                            </div>
                        </div>
                        <div class="logo-small logo-small_2">
                            <div class="logo-small__inner">
                                <img src="pictures/websocket.svg" class="logo-small__img" alt="websocket">
                            </div>
                        </div>
                        <div class="logo-small logo-small_3">
                            <div class="logo-small__inner">
                                <img src="pictures/d3.svg" class="logo-small__img" alt="d3">
                            </div>
                        </div>
                        <div class="logo-small logo-small_4">
                            <div class="logo-small__inner">
                                <img src="pictures/leaflet.svg" class="logo-small__img" alt="leaflet">
                            </div>
                        </div>
                        <div class="logo-small logo-small_5">
                            <div class="logo-small__inner">
                                <img src="pictures/websocket.svg" class="logo-small__img" alt="websocket">
                            </div>
                        </div>
                        <div class="logo-small logo-small_6">
                            <div class="logo-small__inner">
                                <img src="pictures/svg.svg" class="logo-small__img" alt="svg">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <style>
            #intro {
                --logo-animation-time: 12s;
                --logo-offset: 150px;
                --logo-offset-x: 85px;
                --logo-offset-y: 129.903810568px;
                --logo-size: 50px;
            }

            #intro .logo-main {
                animation: intro-spin_forth infinite var(--logo-animation-time) linear;
                position: absolute;
                bottom: 0;
                left: 0;
                margin: auto;
                right: 0;
                top: 0;
                width: 300px;
            }

            #intro .logo-small {
                position: absolute;
                bottom: 0;
                height: var(--logo-size);
                left: 0;
                margin: auto;
                right: 0;
                top: 0;
                width: var(--logo-size);
            }

            #intro .logo-small_1 {
                animation: intro-spin-small_1 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small_2 {
                animation: intro-spin-small_2 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small_3 {
                animation: intro-spin-small_3 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small_4 {
                animation: intro-spin-small_4 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small_5 {
                animation: intro-spin-small_5 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small_6 {
                animation: intro-spin-small_6 infinite var(--logo-animation-time) linear;
            }

            #intro .logo-small__inner {
                left: 50%;
                position: absolute;
                top: 50%;
                transform: translate(-50%, -50%);
            }

            #intro .logo-small__img {
                animation: intro-spin_back infinite var(--logo-animation-time) linear;
                height: var(--logo-size);
            }

            @keyframes intro-spin_forth {
                from {
                    transform: rotate(0deg);
                }
                to {
                    transform: rotate(360deg);
                }
            }

            @keyframes intro-spin_back {
                from {
                    transform: rotate(360deg);
                }
                to {
                    transform: rotate(0deg);
                }
            }

            @keyframes intro-spin-small_1 {
                from {
                    transform: rotate(0deg) translate(var(--logo-offset-x), calc(-1 * var(--logo-offset-y)));
                }
                to {
                    transform: rotate(360deg) translate(var(--logo-offset-x), calc(-1 * var(--logo-offset-y)));
                }
            }

            @keyframes intro-spin-small_2 {
                from {
                    transform: rotate(0deg) translate(var(--logo-offset), 0);
                }
                to {
                    transform: rotate(360deg) translate(var(--logo-offset), 0);
                }
            }

            @keyframes intro-spin-small_3 {
                from {
                    transform: rotate(0deg) translate(var(--logo-offset-x), var(--logo-offset-y));
                }
                to {
                    transform: rotate(360deg) translate(var(--logo-offset-x), var(--logo-offset-y));
                }
            }

            @keyframes intro-spin-small_4 {
                from {
                    transform: rotate(0deg) translate(calc(-1 * var(--logo-offset-x)), var(--logo-offset-y));
                }
                to {
                    transform: rotate(360deg) translate(calc(-1 * var(--logo-offset-x)), var(--logo-offset-y));
                }
            }

            @keyframes intro-spin-small_5 {
                from {
                    transform: rotate(0deg) translate(calc(-1 * var(--logo-offset)), 0);
                }
                to {
                    transform: rotate(360deg) translate(calc(-1 * var(--logo-offset)), 0);
                }
            }

            @keyframes intro-spin-small_6 {
                from {
                    transform: rotate(0deg) translate(calc(-1 * var(--logo-offset-x)), calc(-1 * var(--logo-offset-y)));
                }
                to {
                    transform: rotate(360deg) translate(calc(-1 * var(--logo-offset-x)), calc(-1 * var(--logo-offset-y)));
                }
            }
        </style>
    </section>

    <section class="slide" id="about">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Сухушин Александр</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="about">
                        <a class="link_us" data-title="USERSTORY" href="https://userstory.ru/">USERSTORY</a>
                    </div>
                </div>
            </div>
        </div>
        <style>
            .about {
                align-items: center;
                display: flex;
                flex-direction: column;
                height: 100%;
                justify-content: center;
            }
        </style>
    </section>

    <section class="slide" id="stack">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>React</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <div class="stack">
                            <div class="stack__section">
                                <img class="stack__img" src="pictures/react.svg" alt="react">
                            </div>
                            <div class="stack__section stack__section_divider stack__section_narrow"></div>
                            <div class="stack__section stack__section_hidden">
                                <img class="stack__img" src="pictures/leaflet.svg" alt="react">
                                <img class="stack__img" src="pictures/websocket.svg" alt="redux">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <style>
            .stack {
                align-items: center;
                display: flex;
                flex-direction: column;
                height: 100%;
                justify-content: center;
            }
            .stack__section {
                margin: 20px auto;
                text-align: center;
            }
            .stack__section_narrow {
                width: 300px;
            }
            .stack__section_hidden {
                opacity: 0;
            }
            .stack__section_divider {
                border-bottom: 1px solid #A9B7C6;
            }
            .stack__img {
                height: 100px;
                margin: 10px;
                vertical-align: middle;
            }
        </style>
    </section>

    <section class="slide" id="stack-2">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>React</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <div class="stack">
                            <div class="stack__section">
                                <img class="stack__img" src="pictures/react.svg" alt="react">
                            </div>
                            <div class="stack__section stack__section_divider stack__section_narrow"></div>
                            <div class="stack__section">
                                <img class="stack__img" src="pictures/leaflet.svg" alt="leaflet">
                                <img class="stack__img" src="pictures/websocket.svg" alt="websocket">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="react−leaflet">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>React−Leaflet</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/react-leaflet.png" alt="react−leaflet">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="leaflet">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Leaflet</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/leaflet.png" alt="leaflet">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="map">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map.png" alt="Map">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="tile-layer">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Tile layer</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map-tile-layer.png" alt="Tile layer">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="map-geo-json">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map GeoJSON</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map-geo-json.png" alt="Map GeoJSON">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide slide_code image" id="geo-json">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>GeoJSON</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover o_h">
                        <img src="pictures/geo-json.png" alt="GeoJSON">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="map-view">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map View</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map-view.png" alt="Map View">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="bounds">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Bounds</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover o_h">
                        <img src="pictures/bounds.png" alt="Bounds">
                    </div>
                </div>
            </div>
        </div>
        <style>
            #bounds img {
                bottom: 0;
                left: 0;
                margin: auto;
                position: absolute;
                right: 0;
                top: 0;
            }
        </style>
    </section>

    <section class="slide image" id="map-view-2">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map View</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map-view.png" alt="Map View">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image map-view-joke" id="map-view-joke">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map View</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <input class="map-view-joke__checkbox" id="map-view-joke-checkbox" type="checkbox">
                        <label class="map-view-joke__label" for="map-view-joke-checkbox">
                            <img class="map-view-joke__img" src="pictures/map-view-joke.png" alt="Map View">
                        </label>
                    </div>
                </div>
            </div>
        </div>
        <style>
            .map-view-joke__checkbox {
                display: none;
                position: absolute;
            }
            .map-view-joke__label {
                display: block;
                height: 100%;
                overflow: hidden;
                width: 100%;
            }
            .map-view-joke__img {
                max-width: none !important;
                width: 824px;
            }
            .map-view-joke__checkbox:checked + .map-view-joke__label .map-view-joke__img {
                width: 11520px;
                margin-left: -5420px;
                margin-top: -2930px;
                transition: all 900ms ease-in;
            }
        </style>
    </section>

    <section class="slide image" id="map-usage">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map Usage</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/map-usage.png" alt="Map Usage">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide qr" id="map-example">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Map Example</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover t-a_c">
                        <a href="https://suhushinas.github.io/2019-04-27_renderless-components-example/#/example-map" target="_blank">
                            <img src="pictures/map-example.svg" alt="Map Example">
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="socket-centrifuge">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>WebSockets Centrifuge</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/socket-centrifuge.png" alt="WebSockets Centrifuge">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="socket-subscribe">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>WebSockets Subscribe</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/socket-subscribe.png" alt="WebSockets Subscribe">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide image" id="socket-usage">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>WebSockets Usage</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover">
                        <img src="pictures/socket-usage.png" alt="WebSockets Usage">
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide qr" id="socket-example">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>WebSockets Example</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover t-a_c">
                        <a href="https://suhushinas.github.io/2019-04-27_renderless-components-example/#/example-socket" target="_blank">
                            <img src="pictures/socket-example.svg" alt="WebSockets Example">
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="slide qr" id="questions">
        <div class="box">
            <div class="row">
                <div class="col">
                    <h2>Вопросы</h2>
                </div>
            </div>
            <div class="row h_full">
                <div class="col">
                    <div class="box_cover t-a_c">
                        <a href="https://suhushinas.github.io/2019-04-27_renderless-components/" target="_blank">
                            <img src="pictures/self-link.svg" alt="Self">
                        </a>
                        <a href="https://github.com/SuhushinAS/renderless-components-examples/" target="_blank">
                            <img src="pictures/source.svg" alt="Source">
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <div class="progress"></div>

    <script src="shower/shower.min.js"></script>
    <!-- Copyright © 3000 Yours Truly, Famous Inc. -->

</body>
</html>
